#ifndef _INTERRUPT_CONTROLLER_H_
#define _INTERRUPT_CONTROLLER_H_

#include "types.h"
#include "board_config.h"


/*
 * interrupt_controller.h
 * Processor: TI OMAP L138 (ARM962EJ-S)
 *
*/


/*
* Execution modes:
* 0x10: Normal mode
* 0x11: _fiq, 0x12: _irq, 0x13: _svc, 0x17: Abort, 0x1B: undef, 0x1F: system
*/

// Interrupt controller register definitions
#define ARM_INTC_REV				*((volatile uint32_t *)0xFFFEE000)		// Revison register

#define ARM_INTC_CR				*((volatile uint32_t *)0xFFFEE004)			// Control register

#define ARM_INTC_GER				*((volatile uint32_t *)0xFFFEE010)		// Global interrupt enable register
#define ARM_INTC_GNLR				*((volatile uint32_t *)0xFFFEE01C)		// Global nesting level

#define ARM_INTC_EISR				*((volatile uint32_t *)0xFFFEE028)		// Enable interrupt(s) by writing interrupt index
#define ARM_INTC_EICR				*((volatile uint32_t *)0xFFFEE02C)		// Disable interrupt(s) by writing interrupt index
#define ARM_INTC_ESR(x)				*((volatile uint32_t *)0xFFFEE300 + (4*x))	// Enable interrupt (trigger output to host) by setting appropriate bit
#define ARM_INTC_ECR(x)				*((volatile uint32_t *)0xFFFEE380 + (4*x))	// Disable interrupt (don't map to any channel) by setting appropriate bit
#define ARM_INTC_HIEISR				*((volatile uint32_t *)0xFFFEE034)		// Enable FIQ/IRQ lines to host
#define ARM_INTC_HIEICR				*((volatile uint32_t *)0xFFFEE038)		// Disable FIQ/IRQ lines to host
#define ARM_INTC_HIER(x)			*((volatile uint32_t *)0xFFFEF500 + (4*x))	// Enable FIQ/IRQ individually (set while writing to HIEISR/HIEICR)


#define ARM_INTC_SISR				*((volatile uint32_t *)0xFFFEE020)		// Set raw status of the interrupt
#define ARM_INTC_SICR				*((volatile uint32_t *)0xFFFEE024)		// Clear raw status of the interrupt
#define ARM_INTC_SPSR(x)			*((volatile uint32_t *)0xFFFEE200 + (4*x))	// Set interrupt manually
#define ARM_INTC_SECR(x)			*((volatile uint32_t *)0xFFFEE280 + (4*x))	// Clear interrupt (usually after it has been serviced)

#define ARM_INTC_VBR				*((volatile uint32_t *)0xFFFEE050)		// Interrupt vector base
#define ARM_INTC_VSR				*((volatile uint32_t *)0xFFFEE054)		// Interrupt vector size
#define ARM_INTC_VNR				*((volatile uint32_t *)0xFFFEE058)		// Interrupt null register (??)

#define ARM_INTC_CMR(x)				*((volatile uint32_t *)0xFFFEE400 + (4*x))	// Channel map registers

#define ARM_INTC_GPIR				*((volatile uint32_t *)0xFFFEE080)		// Highest priority pending interrupt (readonly)
#define ARM_INTC_GPVR				*((volatile uint32_t *)0xFFFEE084)		// Vector address of highest priority pending interrupt (readonly)
#define ARM_INTC_HIPIR(x)			*((volatile uint32_t *)0xFFFEE900 + (4*x))	// Highest priority pending FIQ interrupt (readonly)
#define ARM_INTC_DSR(x)				*((volatile uint32_t *)0xFFFEEF00 + (4*x))	// Highest priority pending IRQ interrupt (readonly)
#define ARM_INTC_HINLR(x)			*((volatile uint32_t *)0xFFFEF100 + (4*x))	// Nesting level of the FIQ/IRQ interrupt (read/override)
#define ARM_INTC_HIPVR(x)			*((volatile uint32_t *)0xFFFEF600 + (4*x))	// Vector address of highest priority pending FIQ/IRQ interrupt (readonly)


#define ARM_MAX_INTERRUPTS			101

#define DISABLE_INTERRUPTS()	ARM_INTC_GER = 0
#define ENABLE_INTERRUPTS()	ARM_INTC_GER = 1

// Interrupt vectors
#define commtx_interrupt_handler __interrupt_0_handler
#define commrx_interrupt_handler __interrupt_1_handler


// Interrupt indexes
#define AINTC_COMMTX_INTERRUPT	0
#define AINTC_COMMRX_INTERRUPT	1
#define AINTC_UART0_INTERRUPT 25
#define AINTC_UART1_INTERRUPT 53
#define AINTC_UART2_INTERRUPT 61
#define AINTC_USER_TIMER_INTERRUPT 21
#define AINTC_SPI1_INTERRUPT  56

#define AINTC_EMAC_C0_RX_THRES_INTERRUPT 33
#define AINTC_EMAC_C0_RX_INTERRUPT 34
#define AINTC_EMAC_C0_TX_INTERRUPT 35
#define AINTC_EMAC_C0_MISC_INTERRUPT 36
#define AINTC_EMAC_C1_RX_THRES_INTERRUPT 37
#define AINTC_EMAC_C1_RX_INTERRUPT 38
#define AINTC_EMAC_C1_TX_INTERRUPT 39
#define AINTC_EMAC_C1_MISC_INTERRUPT 40

#if (UART_IN_USE == 0)
#define AINTC_UART_INTERRUPT AINTC_UART0_INTERRUPT
#elif (UART_IN_USE == 1)
#define AINTC_UART_INTERRUPT AINTC_UART1_INTERRUPT
#else
#define AINTC_UART_INTERRUPT AINTC_UART2_INTERRUPT
#endif






void enable_interrupt(uint8_t index);
void initialize_interrupts(void);

void static inline debug_set_interrupt(uint8_t interrupt_index)
{
	ARM_INTC_SISR = interrupt_index;
	return;
}

#endif
